using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using DataService.Helper;
using Opc.Ua;
using Opc.Ua.Client;
using Opc.Ua.Client.Controls;
using Opc.Ua.Export;
using Opc.Ua.Sample.Service;
using OpcuaClient.Model;
using static System.Collections.Specialized.BitVector32;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace OpcuaClient.View
{
    public partial class Form_CollectionConfig : Form
    {
        LogHelper LogHelper = new LogHelper("OpcuaClient");
        private OpcConnectService OpcConnectService { get; set; }
        public List<NodeId> Nodes { get; set; }
        public List<Collection> Collections { get; set; }
        public bool Status { get; set; }

        public Form_CollectionConfig(OpcConnectService opcConnectService)
        {
            InitializeComponent();

            OpcConnectService = opcConnectService;
            Collections = new List<Collection>();
            Nodes = new List<NodeId>();
            //初始化控件数据
            InitConfig();

            InitListView();
        }

        /// <summary>
        /// Handles the AfterSelect event of the BrowseTV control.
        /// </summary>
        private void BrowseTV_AfterSelect(object sender, EventArgs e)
        {
            try
            {
                if (browseTreeViewCtrl1.SelectedNode == null)
                {
                    return;
                }

                // get node to browse.
                ReferenceDescription reference = (ReferenceDescription)browseTreeViewCtrl1.SelectedNode;
                NodeId nodeId = null;

                if (reference != null)
                {
                    nodeId = (NodeId)reference.NodeId;
                    ReadAttribute(nodeId);
                }
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException(this.Text, exception);
            }
        }

        /// <summary>
        /// Handles the AfterSelect event of the BrowseTV control.
        /// </summary>
        private void BrowseTV_NodeDoubleClick(object sender, EventArgs e)
        {
            try
            {
                if (browseTreeViewCtrl1.SelectedNode == null)
                {
                    return;
                }

                // get node to browse.
                ReferenceDescription reference = (ReferenceDescription)browseTreeViewCtrl1.SelectedNode;
                NodeId nodeId = null;

                if (reference != null)
                {
                    nodeId = (NodeId)reference.NodeId;
                    Nodes.Add(nodeId);
                    ConfigCollection(nodeId);
                }
            }
            catch (Exception exception)
            {
                ClientUtils.HandleException(this.Text, exception);
            }
        }

        private void btSave_Click(object sender, EventArgs e)
        {
            Status = true;
            Close();
        }

        private void btCancel_Click(object sender, EventArgs e)
        {
            Status = false;
            Close();
        }

        /// <summary>
        /// 切换OPC CLIENT服务器
        /// </summary>
        /// <param name="session"></param>
        public void InitConfig()
        {
            try
            {
                //加载OPC 服务
                browseTreeViewCtrl1.Initialize(OpcConnectService.Session, ObjectIds.ObjectsFolder, ReferenceTypeIds.Organizes, ReferenceTypeIds.Aggregates);
                //初始化 ATRRIBUTE
                attributesListViewCtrl1.ChangeSession(OpcConnectService.Session);
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex.Message);
            }
        }

        /// <summary>
        /// 加载当前OPC点位
        /// </summary>
        /// <param name="node"></param>
        bool Read { get; set; }
        Thread AttributeReadThread;
        private void ReadAttribute(NodeId node)
        {
            Read = false;
            Thread.Sleep(1000);
            if (AttributeReadThread != null/* && AttributeReadThread.IsAlive*/) { AttributeReadThread.Abort(); }
            Read = true;
            AttributeReadThread = new Thread(() => {
                while (Read)
                {
                    attributesListViewCtrl1.ReadAttributes(node, true);
                    Thread.Sleep(600);
                }
            });
            AttributeReadThread.Start();
        }
        /// <summary>
        /// 配置/初始化点位信息
        /// </summary>
        /// <param name="node"></param>
        private void ConfigCollection(NodeId node)
        {
            Form_Collection collection = new Form_Collection();
            collection.InitCollection(node);
            collection.ShowDialog(this);
            if (collection.Status)
            {
                Collections.Add(collection.Collection);
                AddCollectToListView(collection.Collection);
            }
        }

        private void btAddFixed_Click(object sender, EventArgs e)
        {
            Form_Collection collection = new Form_Collection();
            collection.ShowDialog(this);

            if (collection.Status)
            {
                Collections.Add(collection.Collection);
                AddCollectToListView(collection.Collection);
            }
        }

        #region ListView Function
        /// <summary>
        /// 绘制表头
        /// </summary>
        private void InitListView()
        {
            lvNodeList.Columns.Add("Key", "Key", 120);
            lvNodeList.Columns.Add("Name", "名称", 150);
            lvNodeList.Columns.Add("ValueType", "值类型", 120);
            lvNodeList.Columns.Add("DataType", "数据类型", 120);
            lvNodeList.Columns.Add("ReadType", "读取方式", 120);
            lvNodeList.Columns.Add("Requency", "刷新频率", 120);
            lvNodeList.Columns.Add("Address", "点位地址", 200);
        }
        /// <summary>
        /// 添加一条记录
        /// </summary>
        /// <param name="collection"></param>
        private void AddCollectToListView(Collection collection)
        {
            if (collection != null)
            {
                lvNodeList.BeginUpdate();
                ListViewItem item = new ListViewItem();
                item.ImageIndex = lvNodeList.Items.Count;
                item.Text = collection.Key;
                item.SubItems.Add(collection.Name);
                item.SubItems.Add(collection.ValueType);
                item.SubItems.Add(collection.DataType);
                item.SubItems.Add(collection.ReadType);
                item.SubItems.Add(collection.Frequency.ToString());
                item.SubItems.Add(collection.Address);
                item.Tag = collection;
                lvNodeList.Items.Add(item);
                lvNodeList.EndUpdate();
            }
        }
        /// <summary>
        /// 删除选项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 删除选中ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var items = lvNodeList.SelectedItems;
            if (items.Count > 0)
            {
                for (int i = 0; i < items.Count; i++)
                {
                    lvNodeList.Items.Remove(items[i]);
                    //删除ListView的同时删除点位
                    RemoveCollect((Collection)items[i].Tag);
                }
            }
        }

        /// <summary>
        /// 删除点位
        /// </summary>
        /// <param name="collection"></param>
        private void RemoveCollect(Collection collection)
        {
            if (collection != null)
            {
                var collect = Collections.FirstOrDefault(m => m.Key == collection.Key);
                Collections.Remove(collection);
            }
        }

        #endregion

        private void Form_CollectionConfig_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (AttributeReadThread != null && AttributeReadThread.IsAlive)
            {
                AttributeReadThread.Abort();
                Thread.Sleep(300);
            }
        }

        private void lvNodeList_DoubleClick(object sender, EventArgs e)
        {
            var items = lvNodeList.SelectedItems;
            if (items.Count == 0) return;
            Collection collection = (Collection)items[0].Tag;
            if (collection == null) return;
            int index = lvNodeList.Items.IndexOf(items[0]);

            Form_Collection formCollection = new Form_Collection();
            formCollection.InitCollection(collection);
            formCollection.ShowDialog(this);
            if (formCollection.Status)
            {
                int idx = Collections.FindIndex(m => m.Key == formCollection.Collection.Key);
                if (idx > -1)
                {
                    Collections[idx] = formCollection.Collection;
                }
                ListViewItem item = new ListViewItem();
                item.ImageIndex = index;
                item.Text = collection.Key;
                item.SubItems.Add(collection.Name);
                item.SubItems.Add(collection.ValueType);
                item.SubItems.Add(collection.DataType);
                item.SubItems.Add(collection.ReadType);
                item.SubItems.Add(collection.Frequency.ToString());
                item.SubItems.Add(collection.Address);
                item.Tag = formCollection.Collection;

                lvNodeList.Items[index] = item;
            }
        }
    }
}
